package com.java.basis.thread.pool;

import java.util.concurrent.*;


/**
 * @author wangning
 * @date 2023/5/16 15:21
 * 线程池的基本使用
 */
public class MyThreadPoolDemo {
    public static void main(String[] args) {
        //怎么合理设计线程池
        //一个物理CPU可以有1个或者多个物理内核
        //一个物理内核可以作为1个或者2个逻辑CPU。
        //CPU密集型，一般设计，CPU核数+1，for循环
        //IO密集型 CPU核数*2 磁盘读取，参考公式 CPU核数/1-阻塞系数，阻塞系数在0.8到0.9之间
        //IO密集型 直接放在服务器上进行压测，然后选取合适的值
        System.out.println(Runtime.getRuntime().availableProcessors());//14和20线程

    }

    /**
     * 拒绝策略
     */
    private static void refuse() {
        ExecutorService threadPool = new ThreadPoolExecutor(2,
                5,
                1L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
//                new ThreadPoolExecutor.AbortPolicy());//抛出异常
//                new ThreadPoolExecutor.CallerRunsPolicy());//谁调我，回退给谁
//                new ThreadPoolExecutor.DiscardOldestPolicy());//放弃等待时间最久的
                new ThreadPoolExecutor.DiscardPolicy());//直接拒绝新来的
        try {
            for (int i = 1; i <= 11; i++) {
                final int temp = i;

                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t 办理业务" + temp);
                });
                try {
                    TimeUnit.MILLISECONDS.sleep(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }

    /**
     * 线程的基本使用
     */
    private static void threadInit() {

        ExecutorService threadPool = Executors.newFixedThreadPool(5);//固定数线程，一池5个处理线程//核心线程数=最大线程数
//        ExecutorService threadPool = Executors.newSingleThreadExecutor();//一池只有1个处理线程
//        ExecutorService threadPool = Executors.newCachedThreadPool();//一池N个处理线程//核心线程数为0

        //模拟10个用户办理业务，每个用户就是一个来自外部的请求线程
        try {
            for (int i = 1; i <= 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t 办理业务");
                });
                try {
                    TimeUnit.MILLISECONDS.sleep(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}
